package org.example.product.service.impl;

import cn.hutool.core.util.StrUtil;
import org.example.core.exception.CustomException;
import org.example.core.exception.ExceptionCode;
import org.example.core.utils.R;
import org.example.product.api.CouponService;
import org.example.product.api.SearchService;
import org.example.product.api.SeckillService;
import org.example.product.api.WareHouseService;
import org.example.product.api.domain.*;
import org.example.product.api.module.SeckillSkuInfo;
import org.example.product.dao.*;
import org.example.product.entity.*;
import org.example.product.service.ProductService;
import org.example.product.vo.*;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.stream.Collectors;

/**
 * @author 小杰_cc
 * @version 1.0
 */
@Service
public class ProductServiceImpl implements ProductService {

    @Autowired
    private SpuInfoDao spuInfoDao;
    @Autowired
    private SpuDescDao spuDescDao;
    @Autowired
    private SpuAttributeDao spuAttributeDao;
    @Autowired
    private SkuInfoDao skuInfoDao;
    @Autowired
    private SkuImagesDao skuImagesDao;
    @Autowired
    private SkuAttributeDao skuAttributeDao;
    @Autowired
    private BrandDao brandDao;
    @Autowired
    private CategoryDao categoryDao;
    @Autowired
    private SearchService searchService;
    @Autowired
    private CouponService couponService;
    @Autowired
    private WareHouseService wareHouseService;
    @Autowired
    private ThreadPoolExecutor threadPoolExecutor;
    @Autowired
    private SeckillService seckillService;

    /**
     * 保存商品
     * @param spuRestVo
     * @return
     */
    @Override
    @Transactional
    public void saveProduct(SpuRestVo spuRestVo) {
        // 保存spu基本信息
        SpuInfoEntity spuInfo = new SpuInfoEntity();
        BeanUtils.copyProperties(spuRestVo,spuInfo);
        spuInfo.setCreateTime(LocalDateTime.now());
        spuInfo.setUpdateTime(LocalDateTime.now());
        spuInfoDao.addSpuInfo(spuInfo);

        // 保存spu介绍图片信息
        if(StrUtil.isNotBlank(spuRestVo.getContent())){
            spuDescDao.addSpuContent(spuInfo.getSpuId(),spuRestVo.getContent());
        }

        // 保存spu参数信息
        if(spuRestVo.getAttrParamsArray() != null && spuRestVo.getAttrParamsArray().size() >0){
            spuAttributeDao.addSpuAttribute(spuInfo.getSpuId(),spuRestVo.getAttrParamsArray());
        }

        // 保存sku信息,一项一项来
        List<WareSku> wareSkus = new ArrayList<>();
        if (spuRestVo.getSkus() != null && spuRestVo.getSkus().size() >0) {
            spuRestVo.getSkus().forEach(skuRestVo -> {
                // 保存基本信息
                SkuInfoEntity skuInfo = new SkuInfoEntity();
                BeanUtils.copyProperties(skuRestVo,skuInfo);
                skuInfo.setSpuId(spuInfo.getSpuId());   // spuId
                skuInfo.setCategoryId(spuInfo.getCategoryId());  // categoryId
                skuInfo.setBrandId(spuInfo.getBrandId()); // brandId
                skuInfo.setCreateTime(LocalDateTime.now());
                skuInfo.setUpdateTime(LocalDateTime.now());
                // 没有设置默认，选择的第一张为默认
                if(StrUtil.isBlank(skuInfo.getSkuDefaultImg()) && (skuRestVo.getImages()!= null && skuRestVo.getImages().size() >0)){
                    skuInfo.setSkuDefaultImg(skuRestVo.getImages().get(0).getImgUrl());
                }
                // 保存基本信息
                skuInfoDao.addSkuInfo(skuInfo);
                // 保存图片信息
                skuImagesDao.addSkuImages(skuInfo.getSkuId(),skuRestVo.getImages());
                // 保存销售属性
                skuAttributeDao.addSkuAttribute(skuInfo.getSkuId(),skuRestVo.getAttribute());
                // 保存折扣信息,1不打折直接排除,前端没处理会自带一个，如果没设置使用JSR303会直接保存失败,如果前端处理掉了可以直接使用JSR303
                Preferential preferential = new Preferential();
                List<SkuLadder> ladderVos = skuRestVo.getLadders().stream()
                        .filter(item -> {
                                    if (item.getCount() == null){
                                        return false;
                                    }else{
                                        return item.getCount() > 0 && item.getDiscount().compareTo(new BigDecimal("0.1")) >=0 && item.getDiscount().compareTo(BigDecimal.ONE) <0;
                                    }
                                })
                        .peek(item -> item.setSkuId(skuInfo.getSkuId())).collect(Collectors.toList());
                preferential.setSkuLadder(ladderVos);
                // 保存满减信息
                List<SkuFullReduction> fullReductionVos = skuRestVo.getFullReductions().stream()
                        .filter(item -> item.getFullPrice().compareTo(BigDecimal.ZERO) > 0 && item.getReducePrice().compareTo(BigDecimal.ZERO) > 0
                ).peek(item -> item.setSkuId(skuInfo.getSkuId())).collect(Collectors.toList());
                preferential.setSkuFullReduction(fullReductionVos);
                couponService.addPreferential(preferential);

                WareSku wareSku = new WareSku();
                wareSku.setSkuId(skuInfo.getSkuId());
                wareSku.setStock(skuRestVo.getStock());
                wareSku.setStockLocked(skuRestVo.getStockLocked());
                wareSku.setSkuName(skuInfo.getSkuTitle());
                wareSkus.add(wareSku);
            });
        }
        // 保存库存
        wareHouseService.saves(wareSkus);
    }

    // 商品上架
    @Override
    public void productUp(Long spuId) {
        // 查询sku商品集合
        List<SkuInfoEntity> entities = skuInfoDao.getSkuInfoBySpuId(spuId);
        if(entities != null && entities.size() > 0){
            // 取一个
            SkuInfoEntity skuInfo = entities.get(0);
            // 设置品牌名,都是一样的只查询一次
            BrandNameLogoVo brandNameLogoVo = brandDao.getBrandNameAndLogoById(skuInfo.getBrandId());
            // 设置spu标题
            String spuTitle = spuInfoDao.getSpuTitleById(skuInfo.getSpuId());
            // 设置可检索的参数信息
            List<Attributes> attributeEntities = spuAttributeDao.getAttributeListBySpuId(spuId);
            List<Attributes> attributesList = new ArrayList<>();
            // 处理多值
            for (Attributes item : attributeEntities) {
                for (String val : item.getValue().split("；")) {
                    Attributes attributes = new Attributes();
                    attributes.setAttributeId(item.getAttributeId());
                    attributes.setAttributeName(item.getAttributeName());
                    attributes.setValue(val);
                    attributesList.add(attributes);
                }
            }
            SkuEsModule skuEsModule = new SkuEsModule();
            BeanUtils.copyProperties(skuInfo, skuEsModule);
            skuEsModule.setSpuTitle(spuTitle);
            skuEsModule.setBrandName(brandNameLogoVo.getName());
            skuEsModule.setLogoUrl(brandNameLogoVo.getLogoUrl());
            skuEsModule.setAttributes(attributesList);
            R<Boolean> stock = wareHouseService.isStock(skuInfo.getSkuId());
            if (stock.getCode() == 0){
                skuEsModule.setHasStock(stock.getData());
                R<?> r = searchService.EsProductUp(skuEsModule);
                if (r.getCode() == 0){
                    spuInfoDao.updateSpuStatus(spuId,0);
                }else {
                    throw new CustomException(ExceptionCode.SPU_UP_ERROR.getCode(), ExceptionCode.SPU_UP_ERROR.getMsg());
                }
            }else {
                throw new CustomException(ExceptionCode.SPU_UP_ERROR.getCode(), ExceptionCode.SPU_UP_ERROR.getMsg());
            }
        }else{
            throw new CustomException(ExceptionCode.SKU_ZERO_ERROR.getCode(), ExceptionCode.SKU_ZERO_ERROR.getMsg());
        }
    }

    // 前台商品信息
    @Override
    public SkuItemVo productInfo(Long skuId) throws ExecutionException, InterruptedException {
        SkuItemVo itemVo = new SkuItemVo();

        CompletableFuture<SkuInfoEntity> supplyAsync = CompletableFuture.supplyAsync(() -> {
            // 获取到基本信息
            SkuInfoEntity skuInfo = skuInfoDao.getSkuInfoBySkuId(skuId);
            itemVo.setSkuInfo(skuInfo);
            return skuInfo;
        }, threadPoolExecutor);

        CompletableFuture<Void> saleAttrFuture = supplyAsync.thenAcceptAsync((res) -> {
            // 获取spu销售属性
            List<SkuSaleAttributeVo> saleAttributeVos = skuInfoDao.getSaleAttributeValue(res.getSpuId());
            itemVo.setSaleAttributes(saleAttributeVos);
        }, threadPoolExecutor);

        CompletableFuture<Void> descFuture = supplyAsync.thenAcceptAsync((res) -> {
            // 获取 spu介绍
            String spuDesc = spuDescDao.getSpuDescBySpuId(res.getSpuId());
            itemVo.setSpuDesc(spuDesc);
        }, threadPoolExecutor);

        CompletableFuture<Void> attrFuture = supplyAsync.thenAcceptAsync((res) -> {
            // spu参数信息
            List<SpuAttributeVo> attributeList = spuAttributeDao.getAttributeVoListBySpuId(res.getSpuId());
            itemVo.setSpuAttributes(attributeList);
        }, threadPoolExecutor);

        CompletableFuture<Void> imgFuture = CompletableFuture.runAsync(() -> {
            // 获取sku图片集合
            List<String> images = skuImagesDao.getSkuImagesList(skuId);
            itemVo.setImages(images);
        }, threadPoolExecutor);

        CompletableFuture<Void> stockFuture = CompletableFuture.runAsync(() -> {
            // 获取sku图片集合
            Integer stock = wareHouseService.queryStock(skuId).getData();
            itemVo.setStock(stock);
        }, threadPoolExecutor);

//        CompletableFuture<Void> seckillFuture = CompletableFuture.runAsync(() -> {
//            // 获取sku秒杀信息
//            SeckillSkuInfo seckillSkuInfo = seckillService.getSeckillSku(skuId).getData();
//            itemVo.setSeckillSkuInfo(seckillSkuInfo);
//        }, threadPoolExecutor);

//        CompletableFuture.allOf(saleAttrFuture, descFuture, attrFuture, imgFuture, stockFuture, seckillFuture).get();
        CompletableFuture.allOf(saleAttrFuture, descFuture, attrFuture, imgFuture, stockFuture).get();

        return itemVo;
    }

    // 商品下架
    @Override
    public R<?> productDown(List<Long> spuIds) {
        int count = spuInfoDao.productDown(spuIds);
        if (count > 0){
            R<?> down = searchService.EsProductDown(spuIds);
            if (down.getCode() != 0){
                throw new CustomException(ExceptionCode.SPU_DOWN_ERROR.getCode(), ExceptionCode.SPU_DOWN_ERROR.getMsg());
            }
        }else {
            return R.error("下架失败");
        }
        return R.ok();
    }
}
